package com.teddy.view;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.xml.sax.SAXException;

import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.teddy.controller.ApplicationManager;
import com.teddy.controller.RDFSchemaControl;
import com.teddy.customWidgets.ModelPropertiesGroup;
import com.teddy.customWidgets.NewConceptDialog;
import com.teddy.customWidgets.RDFSPropertiesGroup;
import com.teddy.customWidgets.ResourcePropertiesGroup;
import com.teddy.customWidgets.SaveDialog;
import com.teddy.model.abstracts.SemanticObject;
import com.teddy.model.skos.DC;
import com.teddy.model.skos.DCModel;
import com.teddy.model.skos.SKOS;
import com.teddy.util.Constants;
import com.teddy.util.FileManager;
import com.teddy.view.tree.ModelTreeItem;
import com.teddy.view.tree.SemanticTree;
import com.teddy.view.tree.SemanticTreeItem;
import com.teddy.view.tree.TaxonomyTreeItem;
import com.teddy.view.tree.ThesaurusTreeITem;

public class BaseGUI {
	/* Constants */
	static final int SASH_WIDTH = 3;
	static final int SASH_LIMIT = 20;
	
	/* Instances */
	static RDFSchemaControl instance;
	private static SemanticTreeItem selectedItem;
	
	Shell shell;
	Display display;
	
	Composite gui;
	Composite mainSashComposite;
	
	Sash leftSash = null;
	
	Group baseGroup;
	Group leftMenuGroup;
	Group centerGroup;
		
	ModelPropertiesGroup    metaDataGroup;
	ResourcePropertiesGroup propertiesGroup;
	RDFSPropertiesGroup     rdfsGroup;
	
	CoolBar coolBar;
	CoolItem coolItem;
	
	TabFolder leftMenuTabFolder;
	
	SemanticTree treeHierarchy;
	
	List searchResultsList;
	
	/*MetaData fields*/
	private static Text metaTitle;
	private static Text metaAltTitle;
	private static Text metaDescription;
	private static Text metaPublisher;
	private static Text metaIdentifier;
	private static Text metaSource;
	private static ExpandBar metaExpandBar;
	private static ExpandItem metaLanguage;
	private static ExpandItem metaSubject;
	
	/*Resource properties fields*/
	private static Text resPrefLabel;
	private static Text resPrefSymbol;
	private static Text resAltLabel;
	private static Text resAltSymbol;
	private static Text resScopeNote;
	private static Text resDefinition;
	private static Text resNotation;
	private static ExpandBar resExpandBar;
	private static ExpandItem resInSchema;
	private static ExpandItem resHasTopConcept;
	private static ExpandItem resNarrower;
	private static ExpandItem resBroader;
	private static ExpandItem resRelated;
	
	/*RDFS properties fields*/
	private static Text rdfsComment;
	private static Text rdfsLabel;
	private static Link rdfsDomain;
	private static Link rdfsIsDefinedBy;
	private static Link rdfsMember;
	private static Link rdfsRange;
	private static Link rdfsSeeAlso;
	private static Link rdfsSubClassOf;
	private static Link rdfsSubPropertyOf;
	
	private ApplicationManager manager;
	
	/* Constructor */
	public BaseGUI( RDFSchemaControl instance ) throws IOException, ParserConfigurationException, SAXException {
		manager = ApplicationManager.getInstance();
		manager.loadApplication();
		BaseGUI.instance = instance;
	}
	
	/* Methods */
	
	public Composite createGUIPage (Composite parent) throws IOException {
		/* Cache the shell and display. */
		shell = parent.getShell ();
		display = shell.getDisplay ();
		shell.setText( RDFSchemaControl.getResourceString( "window.title" ));
		
		gui = new Composite (parent, SWT.NONE);
		gui.setLayout (new GridLayout(1, false));
		
		createButtonBar();
		
		createMainSashComponents();
		createLeftMenuGroup();
		createCenterGroup();
		
		createLeftMenuContent();
		
		return gui;
	}
	
	private void createButtonBar(){
		coolBar = new CoolBar( gui, SWT.NONE );	
		coolBar.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ));
		
		ToolBar buttonBar = new ToolBar( coolBar, SWT.FLAT );		
		buttonBar.setLayout(new FillLayout());
		buttonBar.setLayoutData( new GridData( SWT.BEGINNING, SWT.TOP, true, false));
		
		ToolItem importBtn = new ToolItem(buttonBar, SWT.PUSH);		
		importBtn.setToolTipText(Constants.IMPORT);
		importBtn.setImage(FileManager.getImage( RDFSchemaControl.getResourceString( "icon.export") ));
		importBtn.addSelectionListener(new ImportModelListener());	
		
		ToolItem exportBtn = new ToolItem(buttonBar, SWT.PUSH);		
		exportBtn.setToolTipText(Constants.EXPORT);
		exportBtn.setImage(FileManager.getImage( RDFSchemaControl.getResourceString( "icon.import") ));
		exportBtn.addSelectionListener(new ExportModelListener());	
		
		ToolItem refresh = new ToolItem(buttonBar, SWT.PUSH);
		refresh.setToolTipText("Refresh");
		refresh.addSelectionListener(new RefreshTree());
		refresh.setImage(FileManager.getImage( RDFSchemaControl.getResourceString( "icon.refresh") ));
		
		new ToolItem( buttonBar, SWT.SEPARATOR );
		
		ToolItem addConcept = new ToolItem(buttonBar, SWT.PUSH);
		addConcept.setToolTipText("Add concept");
		addConcept.addSelectionListener(new NewConceptListener());
		addConcept.setImage(FileManager.getImage( RDFSchemaControl.getResourceString( "icon.addConcept") ));
		
		ToolItem removeResourceBtn = new ToolItem(buttonBar, SWT.PUSH);		
		removeResourceBtn.setToolTipText("Remove");
		removeResourceBtn.setImage(FileManager.getImage( RDFSchemaControl.getResourceString( "icon.removeFolder") ));
		removeResourceBtn.addSelectionListener(new RemoveConceptListener());
		
		
		coolItem = new CoolItem( coolBar, SWT.NONE );
		coolItem.setControl( buttonBar );
		coolItem.addSelectionListener( new CoolItemSelectionListener());
		
		/* Set the sizes after adding all cool items */
		CoolItem[] coolItems = coolBar.getItems();
		for (int i = 0; i < coolItems.length; i++) {
			CoolItem coolItem = coolItems[i];
			Control control = coolItem.getControl();
			Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			Point coolSize = coolItem.computeSize(size.x, size.y);
			if (control instanceof ToolBar) {
				ToolBar bar = (ToolBar)control;
				if (bar.getItemCount() > 0) {
					
						size.x = bar.getItem(0).getWidth();
				}
			}
			coolItem.setMinimumSize(size);
			coolItem.setPreferredSize(coolSize);
			coolItem.setSize(coolSize);
		}
		
	}
	
	protected void createBaseGroup() {
		baseGroup = new Group( gui, SWT.NONE );
		baseGroup.setLayout(new FillLayout());
		baseGroup.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ));
	}
	
	protected void createMainSashComponents() {
		mainSashComposite = new Composite(gui, SWT.NONE );
		mainSashComposite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ));
		/* Create left sash */
		leftSash = new Sash( mainSashComposite, SWT.VERTICAL | SWT.NONE );
				
		/* Create listeners */
		leftSash.addSelectionListener( new SelectionAdapter() {
			public void widgetSelected (SelectionEvent event) {
				Rectangle rect = leftSash.getParent().getClientArea();
				event.x = Math.min (Math.max (event.x, SASH_LIMIT), rect.width - 2*SASH_LIMIT);
				if (event.detail != SWT.DRAG) {
					leftSash.setBounds (event.x, event.y, event.width, event.height);
					redrawLayout();
				}
			}
		});
				
		mainSashComposite.addControlListener (new ControlAdapter() {
			public void controlResized (ControlEvent event) {
				resizeGUI();
			}
		});
	}
	
	protected void createLeftMenuGroup() {
		leftMenuGroup = new Group (mainSashComposite, SWT.V_SCROLL | SWT.H_SCROLL );
		leftMenuGroup.setLayout (new GridLayout ());
		leftMenuGroup.setLayoutData (new GridData (SWT.FILL, SWT.FILL, false, true));
	}
	
	protected void createLeftMenuContent() throws IOException {
		leftMenuTabFolder = new TabFolder( leftMenuGroup, SWT.NONE );
		leftMenuTabFolder.setLayout(new GridLayout() );
		leftMenuTabFolder.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true));
		
		TabItem treeTabItem = new TabItem( leftMenuTabFolder, SWT.NONE );
		treeTabItem.setText("Tree");
		
		treeHierarchy = new SemanticTree( leftMenuTabFolder, SWT.NONE );
		treeTabItem.setControl( treeHierarchy );
		
		createTree();
		
		treeHierarchy.addListener( SWT.Expand, new Listener() {
			
			@Override
			public void handleEvent(Event e) {
				SemanticTreeItem selectedItem =  (SemanticTreeItem) e.item;
				try {
					selectedItem.expand();
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		TabItem searchTabItem = new TabItem( leftMenuTabFolder, SWT.NONE );
		searchTabItem.setText("Search");
		searchResultsList = new List( leftMenuTabFolder, SWT.WRAP | SWT.NONE );
		searchTabItem.setControl( searchResultsList );
		
	}
	
	private void createTree() throws IOException {
		addTreeSelectionListener();
		
		for(SemanticObject so : manager.getThPoolMembers()){
			ModelTreeItem item = new ModelTreeItem(treeHierarchy, SWT.NONE, so);
			item.setBackground(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
		}
		
		for(SemanticObject so : manager.getTaxPoolMembers()){
			ModelTreeItem item = new ModelTreeItem(treeHierarchy, SWT.NONE, so);
			item.setBackground(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT));
		}
	}
	
	private void createCenterGroup() {
		
		centerGroup = new Group( mainSashComposite, SWT.NONE );
		centerGroup.setLayout( new GridLayout() );
		centerGroup.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true));
	}
	
	private void createMetaDataGroup(ModelTreeItem item) {
		if( metaDataGroup != null && !metaDataGroup.isDisposed()) {
			metaDataGroup.dispose();
		}
		metaDataGroup = new ModelPropertiesGroup( centerGroup, SWT.V_SCROLL | SWT.H_SCROLL , item);
			
	}
	
	private void createMetaDataContent() {
		if( metaDataGroup != null )
			try {
				metaDataGroup.createContent();
			} catch (Exception e) {
			/*	MessageBox message = new MessageBox( shell, SWT.OK );
				message.setText( "Error" );
				message.setMessage( e.getMessage() );*/
				metaDataGroup.dispose();
				//e.printStackTrace();*/
			}
	}
	
	protected void createPropertiesGroup(ThesaurusTreeITem item){
		if( propertiesGroup != null && !propertiesGroup.isDisposed()) {
			propertiesGroup.dispose();
		}
		
		propertiesGroup = new ResourcePropertiesGroup( centerGroup, SWT.V_SCROLL | SWT.H_SCROLL ,item);
	}
	
	protected void createPropertiesContent(){
		if( propertiesGroup != null )
			propertiesGroup.createContent();
	}
	
	private void createRDFSGroup(TaxonomyTreeItem item){
		if( rdfsGroup != null && !rdfsGroup.isDisposed()) {
			rdfsGroup.dispose();
		}
		
		rdfsGroup = new RDFSPropertiesGroup( centerGroup, SWT.V_SCROLL | SWT.H_SCROLL , item );
	}
	
	private void createRDFSContent() {
		if( rdfsGroup != null)
			rdfsGroup.createContent();
	}
	
	protected int getDefaultStyle() {
		return SWT.NONE;
	}
	
	protected void redrawLayout() {
		Rectangle clientArea = mainSashComposite.getClientArea ();
		
		Rectangle leftSashBounds = leftSash.getBounds ();
		leftMenuGroup.setBounds(0, 0, leftSashBounds.x, clientArea.height);
		
		centerGroup.setBounds( leftSashBounds.x + leftSashBounds.width, 0,
							   clientArea.width - (leftSashBounds.x + leftSashBounds.width),
							   leftSashBounds.y);
	}
	
	protected void resizeGUI() {
		Rectangle mainClientArea = mainSashComposite.getClientArea ();
		
		Rectangle leftMenuBounds = new Rectangle (0, 0, 
				                                  mainClientArea.width / 4 - SASH_WIDTH / 2,
												  mainClientArea.height );
		leftMenuGroup.setBounds ( leftMenuBounds );
	
		leftSash.setBounds(leftMenuBounds.width, 0, SASH_WIDTH, leftMenuBounds.height);
		
		centerGroup.setBounds( leftMenuBounds.width + SASH_WIDTH, 0,
		  					   mainClientArea.width - ( leftMenuBounds.width + SASH_WIDTH ),
							   leftMenuBounds.height);
	}
	
	/**
	 * Grabs input focus.
	 */
	public void setFocus() {
		gui.setFocus();
	}
	
	private void addTreeSelectionListener() {
		treeHierarchy.addSelectionListener( new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				if( selectedItem == null || !selectedItem.getClass().equals( e.item.getClass())){
					Control[] children = centerGroup.getChildren();
					for (int i = 0; i < children.length; i++) {
						children[i].dispose();
					}
					
					if( e.item instanceof ModelTreeItem ) {
						createMetaDataGroup((ModelTreeItem) e.item);
						createMetaDataContent();
					} else if( e.item instanceof ThesaurusTreeITem ){
						createPropertiesGroup((ThesaurusTreeITem) e.item);
						createPropertiesContent();
					} else if( e.item instanceof TaxonomyTreeItem ){
						createRDFSGroup((TaxonomyTreeItem) e.item);
						createRDFSContent();
					}
					centerGroup.layout(true);
				} else {
					if( e.item instanceof ModelTreeItem ) {
						if( metaDataGroup == null 
								|| metaDataGroup.isDisposed() 
								|| metaDataGroup.getChildren().length == 0 ) {
							createMetaDataGroup((ModelTreeItem) e.item);
							createMetaDataContent();
							centerGroup.layout(true);
						} else {
							updateMetaDataFields( (ModelTreeItem)e.item );
						}
					} else if( e.item instanceof ThesaurusTreeITem ){
						if( propertiesGroup == null 
								|| propertiesGroup.isDisposed()
								|| propertiesGroup.getChildren().length == 0 ) {
							createPropertiesGroup((ThesaurusTreeITem) e.item);
							createPropertiesContent();
							centerGroup.layout(true);
						} else {
							updateResourcePropertiesFields( (ThesaurusTreeITem)e.item );
						}
					} else if( e.item instanceof TaxonomyTreeItem ){
						if( rdfsGroup == null 
								|| rdfsGroup.isDisposed()
								|| rdfsGroup.getChildren().length == 0 ) {
							createRDFSGroup((TaxonomyTreeItem) e.item);
							createRDFSContent();
							centerGroup.layout(true);
						} else {
							updateRDFSPropertiesFields( (TaxonomyTreeItem)e.item);
						}
					}
				}
				selectedItem = (SemanticTreeItem)e.item;
			}
			
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});
		
	}
	
	private void updateMetaDataFields( ModelTreeItem modelTreeItem ) {
		//TODO Set proper fields
		DCModel dcModel = modelTreeItem.getCore().getDcModel();
		if( dcModel != null ) {
			metaTitle.setText( dcModel.getTitle() );
			metaTitle.redraw();
			
			metaAltTitle.setText(dcModel.getSimpleLiteralValue( DC.alternative ) );
			metaAltTitle.redraw();
			
			metaDescription.setText( dcModel.getSimpleLiteralValue( DC.description ) );
			metaDescription.redraw();
			
			metaPublisher.setText( dcModel.getSimpleLiteralValue( DC.publisher ) );
			metaPublisher.redraw();
			
			metaIdentifier.setText( dcModel.getSimpleLiteralValue( DC.identifier ) );
			metaIdentifier.redraw();
			
			metaSource.setText( dcModel.getSimpleLiteralValue( DC.source ) );
			metaSource.redraw();
			
			metaLanguage.getControl().dispose();
			metaLanguage.dispose();
			metaDataGroup.refreshMultipleValueProperty( metaExpandBar, dcModel, "language");
			
			metaSubject.getControl().dispose();
			metaSubject.dispose();
			metaDataGroup.refreshMultipleValueProperty( metaExpandBar, dcModel, "subject");
			
		} else {
			/*MessageBox message = new MessageBox( shell, SWT.OK );
			message.setText( "Error" );
			message.setMessage( "Could not load metadata for " + modelTreeItem.getCore().getName() );
			message.open();*/
			metaDataGroup.dispose();
			metaDataGroup = null;
			centerGroup.layout(true);
		}
		
	}
	
	private void updateResourcePropertiesFields( ThesaurusTreeITem thesaurusTreeItem ){
		//TODO Set proper field values
		
		resPrefLabel.setText( thesaurusTreeItem.getLiteralProperty( SKOS.prefLabel));
		resPrefLabel.redraw();
		
		resPrefSymbol.setText( thesaurusTreeItem.getLiteralProperty( SKOS.prefSymbol));
		resPrefSymbol.redraw();
		
		resAltLabel.setText( thesaurusTreeItem.getLiteralProperty( SKOS.altLabel));
		resAltLabel.redraw();
		
		resAltSymbol.setText( thesaurusTreeItem.getLiteralProperty( SKOS.altSymbol ));
		resAltSymbol.redraw();
		
		//resScopeNote.setText( thesaurusTreeItem.getLiteralProperty( SKOS.scopeNote ));
		//resScopeNote.redraw();
		
		resDefinition.setText( thesaurusTreeItem.getLiteralProperty( SKOS.definition ));
		resDefinition.redraw();
		
		resNotation.setText( thesaurusTreeItem.getLiteralProperty( SKOS.notation ));
		resNotation.redraw();
		
		resInSchema.getControl().dispose();
		resInSchema.dispose();
		
		resHasTopConcept.getControl().dispose();
		resHasTopConcept.dispose();
		
		resNarrower.getControl().dispose();
		resNarrower.dispose();
		
		resBroader.getControl().dispose();
		resBroader.dispose();
		
		resRelated.getControl().dispose();
		resRelated.dispose();
		
		propertiesGroup.refreshMultipleValueProperties( resExpandBar, thesaurusTreeItem );
	}
	
	private void updateRDFSPropertiesFields( TaxonomyTreeItem taxonomyTreeItem ){
		//TODO Set proper fields values
		
		rdfsComment.setText( taxonomyTreeItem.getLiteralProperty( RDFS.comment ));
		rdfsComment.redraw();
		
		rdfsLabel.setText( taxonomyTreeItem.getLiteralProperty( RDFS.label ));
		rdfsLabel.redraw();
		
		rdfsDomain.setText( taxonomyTreeItem.getLiteralProperty( RDFS.domain ));
		rdfsDomain.redraw();
		
		rdfsIsDefinedBy.setText( taxonomyTreeItem.getLiteralProperty( RDFS.isDefinedBy ));
		rdfsIsDefinedBy.redraw();
		
		rdfsMember.setText( taxonomyTreeItem.getLiteralProperty( RDFS.member ));
		rdfsMember.redraw();
		
		rdfsRange.setText( taxonomyTreeItem.getLiteralProperty( RDFS.range ));
		rdfsRange.redraw();
		
		rdfsSeeAlso.setText( taxonomyTreeItem.getLiteralProperty( RDFS.seeAlso ));
		rdfsSeeAlso.redraw();
		
		rdfsSubClassOf.setText( taxonomyTreeItem.getLiteralProperty( RDFS.subClassOf ));
		rdfsSubClassOf.redraw();
		
		rdfsSubPropertyOf.setText( taxonomyTreeItem.getLiteralProperty( RDFS.subPropertyOf ));
		rdfsSubPropertyOf.redraw();
	}
	
	public static void setMetaTitle(Text metaTitle) {
		BaseGUI.metaTitle = metaTitle;
	}

	public static Text getMetaTitle() {
		return metaTitle;
	}

	public static void setMetaAltTitle(Text metaAltTitle) {
		BaseGUI.metaAltTitle = metaAltTitle;
	}

	public static Text getMetaAltTitle() {
		return metaAltTitle;
	}

	public static void setMetaDescription(Text metaDescription) {
		BaseGUI.metaDescription = metaDescription;
	}

	public static Text getMetaDescription() {
		return metaDescription;
	}

	public static void setMetaPublisher(Text metaPublisher) {
		BaseGUI.metaPublisher = metaPublisher;
	}

	public static Text getMetaPublisher() {
		return metaPublisher;
	}

	public static void setMetaIdentifier(Text metaIdentifier) {
		BaseGUI.metaIdentifier = metaIdentifier;
	}

	public static Text getMetaIdentifier() {
		return metaIdentifier;
	}

	public static void setMetaSource(Text metaSource) {
		BaseGUI.metaSource = metaSource;
	}

	public static Text getMetaSource() {
		return metaSource;
	}

	public static void setMetaExpandBar(ExpandBar metaExpandBar) {
		BaseGUI.metaExpandBar = metaExpandBar;
	}

	public static ExpandBar getMetaExpandBar() {
		return metaExpandBar;
	}

	public static void setMetaLanguage(ExpandItem metaLanguage) {
		BaseGUI.metaLanguage = metaLanguage;
	}

	public static ExpandItem getMetaLanguage() {
		return metaLanguage;
	}

	public static void setMetaSubject(ExpandItem metaSubject) {
		BaseGUI.metaSubject = metaSubject;
	}

	public static ExpandItem getMetaSubject() {
		return metaSubject;
	}

	public static void setResPrefLabel(Text resPrefLabel) {
		BaseGUI.resPrefLabel = resPrefLabel;
	}

	public static Text getResPrefLabel() {
		return resPrefLabel;
	}

	public static void setResPrefSymbol(Text resPrefSymbol) {
		BaseGUI.resPrefSymbol = resPrefSymbol;
	}

	public static Text getResPrefSymbol() {
		return resPrefSymbol;
	}

	public static void setResAltLabel(Text resAltLabel) {
		BaseGUI.resAltLabel = resAltLabel;
	}

	public static Text getResAltLabel() {
		return resAltLabel;
	}

	public static void setResAltSymbol(Text resAltSymbol) {
		BaseGUI.resAltSymbol = resAltSymbol;
	}

	public static Text getResAltSymbol() {
		return resAltSymbol;
	}

	public static void setResScopeNote(Text resScopeNote) {
		BaseGUI.resScopeNote = resScopeNote;
	}

	public static Text getResScopeNote() {
		return resScopeNote;
	}

	public static void setResDefinition(Text resDefinition) {
		BaseGUI.resDefinition = resDefinition;
	}

	public static Text getResDefinition() {
		return resDefinition;
	}

	public static void setResNotation(Text resNotation) {
		BaseGUI.resNotation = resNotation;
	}

	public static Text getResNotation() {
		return resNotation;
	}
	
	public static void setResExpandBar(ExpandBar resExpandBar) {
		BaseGUI.resExpandBar = resExpandBar;
	}

	public static ExpandBar getResExpandBar() {
		return resExpandBar;
	}

	public static void setResInSchema(ExpandItem resInSchema) {
		BaseGUI.resInSchema = resInSchema;
	}

	public static ExpandItem getResInSchema() {
		return resInSchema;
	}

	public static void setResHasTopConcept(ExpandItem resHasTopConcept) {
		BaseGUI.resHasTopConcept = resHasTopConcept;
	}

	public static ExpandItem getResHasTopConcept() {
		return resHasTopConcept;
	}

	public static void setResNarrower(ExpandItem resNarrower) {
		BaseGUI.resNarrower = resNarrower;
	}

	public static ExpandItem getResNarrower() {
		return resNarrower;
	}

	public static void setResBroader(ExpandItem resBroader) {
		BaseGUI.resBroader = resBroader;
	}

	public static ExpandItem getResBroader() {
		return resBroader;
	}

	public static void setResRelated(ExpandItem resRelated) {
		BaseGUI.resRelated = resRelated;
	}

	public static ExpandItem getResRelated() {
		return resRelated;
	}

	public static void setRdfsComment(Text rdfsComment) {
		BaseGUI.rdfsComment = rdfsComment;
	}

	public static Text getRdfsComment() {
		return rdfsComment;
	}

	public static void setRdfsLabel(Text rdfsLabel) {
		BaseGUI.rdfsLabel = rdfsLabel;
	}

	public static Text getRdfsLabel() {
		return rdfsLabel;
	}

	public static void setRdfsDomain(Link rdfsDomain) {
		BaseGUI.rdfsDomain = rdfsDomain;
	}

	public static Link getRdfsDomain() {
		return rdfsDomain;
	}

	public static void setRdfsIsDefinedBy(Link rdfsIsDefinedBy) {
		BaseGUI.rdfsIsDefinedBy = rdfsIsDefinedBy;
	}

	public static Link getRdfsIsDefinedBy() {
		return rdfsIsDefinedBy;
	}

	public static void setRdfsMember(Link rdfsMember) {
		BaseGUI.rdfsMember = rdfsMember;
	}

	public static Link getRdfsMember() {
		return rdfsMember;
	}

	public static void setRdfsRange(Link rdfsRange) {
		BaseGUI.rdfsRange = rdfsRange;
	}

	public static Link getRdfsRange() {
		return rdfsRange;
	}

	public static void setRdfsSeeAlso(Link rdfsSeeAlso) {
		BaseGUI.rdfsSeeAlso = rdfsSeeAlso;
	}

	public static Link getRdfsSeeAlso() {
		return rdfsSeeAlso;
	}

	public static void setRdfsSubClassOf(Link rdfsSubClassOf) {
		BaseGUI.rdfsSubClassOf = rdfsSubClassOf;
	}

	public static Link getRdfsSubClassOf() {
		return rdfsSubClassOf;
	}

	public static void setRdfsSubPropertyOf(Link rdfsSubPropertyOf) {
		BaseGUI.rdfsSubPropertyOf = rdfsSubPropertyOf;
	}

	public static Link getRdfsSubPropertyOf() {
		return rdfsSubPropertyOf;
	}

	public static ExpandItem getExpandItem( Property property ) {
		if( property.equals( SKOS.inScheme )) {
			return resInSchema;
		} else if ( property.equals( SKOS.hasTopConcept )) {
			return resHasTopConcept;
		} else if ( property.equals( SKOS.narrower )) {
			return resNarrower;
		} else if( property.equals( SKOS.broader )) {
			return resBroader;
		} else if( property.equals( SKOS.related )) {
			return resRelated;
		}
		return null;
	}
	
	public static void setExpandItem( ExpandItem expandItem, Property property ) {
		if( property.equals( SKOS.inScheme )) {
			resInSchema = expandItem;
		} else if ( property.equals( SKOS.hasTopConcept )) {
			resHasTopConcept = expandItem;
		} else if ( property.equals( SKOS.narrower )) {
			resNarrower = expandItem;
		} else if( property.equals( SKOS.broader )) {
			resBroader = expandItem;
		} else if( property.equals( SKOS.related )) {
			resRelated = expandItem;
		}
	}
	
	public static void setSelectedItem(SemanticTreeItem selectedItem) {
		BaseGUI.selectedItem = selectedItem;
	}

	public static SemanticTreeItem getSelectedItem() {
		return selectedItem;
	}

	/* Inner classes */
	class ImportModelListener implements SelectionListener {
		
	    public void widgetSelected(SelectionEvent event) {
	        FileDialog fd = new FileDialog(shell, SWT.OPEN);
	        fd.setText("Import");
	        fd.setFilterPath("C:/");
	        String[] filterExt = { Constants.THESAUR_FILTER, Constants.XML_FILTER};
	        fd.setFilterExtensions(filterExt);
	        
	        SemanticObject so = manager.importThesaurus(fd.open());
			ModelTreeItem item = new ModelTreeItem(treeHierarchy, SWT.NONE, so);
			item.firstLoad = false;
			
//			try {
//				item.expand();
//
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
			treeHierarchy.redraw();
	    }

	    public void widgetDefaultSelected(SelectionEvent event) {
	    }
	}
	
	class ExportModelListener implements SelectionListener{

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			ModelTreeItem selectedItem = (ModelTreeItem) treeHierarchy.getSelectedItem();
			SaveDialog sd = new SaveDialog(shell, selectedItem.getCore().getURI());
			selectedItem.getCore().createNewUri(sd.open());
			selectedItem.getCore().setFormat(sd.getOutputFormat());
				
			manager.exportThesaurus(selectedItem.getCore());
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			widgetDefaultSelected(e);
		}
	}
	    
	class RemoveConceptListener implements SelectionListener{
	   	@Override
		public void widgetSelected(SelectionEvent e) {
	   		if (treeHierarchy.getSelectedItem()  instanceof ModelTreeItem)
			try {
				manager.removeFromWorkspace(((ModelTreeItem)treeHierarchy.getSelectedItem()).getCore());
				treeHierarchy.getSelectedItem().remove();
				//manager.removeFromWorkspace(treeHierarchy.getSelectedItem());
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			else{
				((ThesaurusTreeITem)treeHierarchy.getSelectedItem()).remove();
			}
	   		try {
				treeHierarchy.getSelectedItem().expand();
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
	   		treeHierarchy.redraw();
		}
			
		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			try {
				treeHierarchy.getSelectedItem().remove();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
	}
	
	class RefreshTree implements SelectionListener{
	   	@Override
		public void widgetSelected(SelectionEvent e) {
	   		treeHierarchy.redraw();
		}
			
		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			try {
				treeHierarchy.getSelectedItem().remove();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
	}
	
	class NewConceptListener implements SelectionListener{
	   	@Override
		public void widgetSelected(SelectionEvent e) {
	   		if (treeHierarchy.getSelectedItem()  instanceof ModelTreeItem){
			try {
				NewConceptDialog dialog  = new NewConceptDialog(shell);
				((ModelTreeItem)treeHierarchy.getSelectedItem()).addNewConcept(dialog.open());
				treeHierarchy.redraw();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
	   		}
		}
			
		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			try {
				treeHierarchy.getSelectedItem().remove();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
	}
	
	class CoolItemSelectionListener extends SelectionAdapter {
		private Menu menu = null;
		
		public void widgetSelected(SelectionEvent event) {
			/**
			 * A selection event will be fired when the cool item
			 * is selected by its gripper or if the drop down arrow
			 * (or 'chevron') is selected. Examine the event detail
			 * to determine where the widget was selected.
			 */
			if (event.detail == SWT.ARROW) {
				/* If the popup menu is already up (i.e. user pressed arrow twice),
				 * then dispose it.
				 */
				if (menu != null) {
					menu.dispose();
					menu = null;
					return;
				}
				
				/* Get the cool item and convert its bounds to display coordinates. */
				CoolItem coolItem = (CoolItem) event.widget;
				Rectangle itemBounds = coolItem.getBounds ();
				itemBounds.width = event.x - itemBounds.x;
				Point pt = coolBar.toDisplay(new Point (itemBounds.x, itemBounds.y));
				itemBounds.x = pt.x;
				itemBounds.y = pt.y;
				
				/* Get the toolbar from the cool item. */
				ToolBar toolBar = (ToolBar) coolItem.getControl ();
				ToolItem[] tools = toolBar.getItems ();
				int toolCount = tools.length;
								
				/* Convert the bounds of each tool item to display coordinates,
				 * and determine which ones are past the bounds of the cool item.
				 */
				int i = 0;
				while (i < toolCount) {
					Rectangle toolBounds = tools[i].getBounds ();
					pt = toolBar.toDisplay(new Point(toolBounds.x, toolBounds.y));
					toolBounds.x = pt.x;
					toolBounds.y = pt.y;
			  		Rectangle intersection = itemBounds.intersection (toolBounds);
			  		if (!intersection.equals (toolBounds)) break;
			  		i++;
				}
				
				/* Create a pop-up menu with items for each of the hidden buttons. */
				menu = new Menu (coolBar);
				for (int j = i; j < toolCount; j++) {
					ToolItem tool = tools[j];
					Image image = tool.getImage();
					if (image == null) {
						new MenuItem (menu, SWT.SEPARATOR);
					} else {
						MenuItem menuItem = new MenuItem (menu, SWT.NONE);
						menuItem.setImage(image);
						String text = tool.getToolTipText();
						if (text != null) menuItem.setText(text);
					}
				}
				
				/* Display the pop-up menu at the lower left corner of the arrow button.
				 * Dispose the menu when the user is done with it.
				 */
				pt = coolBar.toDisplay(new Point(event.x, event.y));
				menu.setLocation (pt.x, pt.y);
				menu.setVisible (true);
				while (menu != null && !menu.isDisposed() && menu.isVisible ()) {
					if (!display.readAndDispatch ()) display.sleep ();
				}
				if (menu != null) {
					menu.dispose ();
					menu = null;
				}
			}
		}
	}
}
